import React, { useCallback, useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { Zap, Loader2, Plus, X, AlertCircle, Save } from "lucide-react";
import type { AppId } from "@/lib/api";
import { vscodeApi } from "@/lib/api/vscode";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from "@/components/ui/dialog";
import type { CustomEndpoint, EndpointCandidate } from "@/types";

// 端点测速超时配置（秒）
const ENDPOINT_TIMEOUT_SECS = {
  codex: 12,
  claude: 8,
  gemini: 8, // 新增 gemini
} as const;

interface TestResult {
  url: string;
  latency: number | null;
  status?: number;
  error?: string | null;
}

interface EndpointSpeedTestProps {
  appId: AppId;
  providerId?: string;
  value: string;
  onChange: (url: string) => void;
  initialEndpoints: EndpointCandidate[];
  visible?: boolean;
  onClose: () => void;
  // 新建模式：当自定义端点列表变化时回传（仅包含 isCustom 的条目）
  // 编辑模式：不使用此回调，端点直接保存到后端
  onCustomEndpointsChange?: (urls: string[]) => void;
}

interface EndpointEntry extends EndpointCandidate {
  id: string;
  latency: number | null;
  status?: number;
  error?: string | null;
}

const randomId = () => `ep_${Math.random().toString(36).slice(2, 9)}`;

const normalizeEndpointUrl = (url: string): string =>
  url.trim().replace(/\/+$/, "");

const buildInitialEntries = (
  candidates: EndpointCandidate[],
  selected: string,
): EndpointEntry[] => {
  const map = new Map<string, EndpointEntry>();
  const addCandidate = (candidate: EndpointCandidate) => {
    const sanitized = candidate.url ? normalizeEndpointUrl(candidate.url) : "";
    if (!sanitized) return;
    if (map.has(sanitized)) return;

    map.set(sanitized, {
      id: candidate.id ?? randomId(),
      url: sanitized,
      isCustom: candidate.isCustom ?? false,
      latency: null,
      status: undefined,
      error: null,
    });
  };

  candidates.forEach(addCandidate);

  const selectedUrl = normalizeEndpointUrl(selected);
  if (selectedUrl && !map.has(selectedUrl)) {
    addCandidate({ url: selectedUrl, isCustom: true });
  }

  return Array.from(map.values());
};

const EndpointSpeedTest: React.FC<EndpointSpeedTestProps> = ({
  appId,
  providerId,
  value,
  onChange,
  initialEndpoints,
  visible = true,
  onClose,
  onCustomEndpointsChange,
}) => {
  const { t } = useTranslation();
  const [entries, setEntries] = useState<EndpointEntry[]>(() =>
    buildInitialEntries(initialEndpoints, value),
  );
  const [customUrl, setCustomUrl] = useState("");
  const [addError, setAddError] = useState<string | null>(null);
  const [autoSelect, setAutoSelect] = useState(true);
  const [isTesting, setIsTesting] = useState(false);
  const [lastError, setLastError] = useState<string | null>(null);
  const [isSaving, setIsSaving] = useState(false);

  // 记录初始的自定义端点，用于对比变化
  const [initialCustomUrls, setInitialCustomUrls] = useState<Set<string>>(
    new Set(),
  );

  const normalizedSelected = normalizeEndpointUrl(value);

  const hasEndpoints = entries.length > 0;
  const isEditMode = Boolean(providerId); // 编辑模式有 providerId

  // 编辑模式：加载已保存的自定义端点
  useEffect(() => {
    let cancelled = false;

    const loadCustomEndpoints = async () => {
      try {
        if (!providerId) return; // 新建模式不加载

        const customEndpoints = await vscodeApi.getCustomEndpoints(
          appId,
          providerId,
        );

        if (cancelled) return;

        const candidates: EndpointCandidate[] = customEndpoints.map(
          (ep: CustomEndpoint) => ({
            url: ep.url,
            isCustom: true,
          }),
        );

        // 记录初始的自定义端点
        const customUrls = new Set(
          customEndpoints.map((ep) => normalizeEndpointUrl(ep.url)),
        );
        setInitialCustomUrls(customUrls);

        // 合并自定义端点与初始端点
        setEntries((prev) => {
          const map = new Map<string, EndpointEntry>();

          // 先添加现有端点
          prev.forEach((entry) => {
            map.set(entry.url, entry);
          });

          // 添加从后端加载的自定义端点
          candidates.forEach((candidate) => {
            const sanitized = normalizeEndpointUrl(candidate.url);
            if (sanitized && !map.has(sanitized)) {
              map.set(sanitized, {
                id: randomId(),
                url: sanitized,
                isCustom: true,
                latency: null,
                status: undefined,
                error: null,
              });
            }
          });

          return Array.from(map.values());
        });
      } catch (error) {
        if (!cancelled) {
          console.error(t("endpointTest.loadEndpointsFailed"), error);
        }
      }
    };

    // 只在编辑模式下加载
    if (providerId) {
      loadCustomEndpoints();
    }

    return () => {
      cancelled = true;
    };
  }, [appId, providerId, t, initialEndpoints]);

  // 新建模式：将自定义端点变化透传给父组件（仅限 isCustom）
  // 编辑模式：不使用此回调，端点已通过 API 直接保存
  useEffect(() => {
    if (!onCustomEndpointsChange || isEditMode) return; // 编辑模式不使用回调
    try {
      const customUrls = Array.from(
        new Set(
          entries
            .filter((e) => e.isCustom)
            .map((e) => (e.url ? normalizeEndpointUrl(e.url) : ""))
            .filter(Boolean),
        ),
      );
      onCustomEndpointsChange(customUrls);
    } catch (err) {
      // ignore
    }
  }, [entries, onCustomEndpointsChange, isEditMode]);

  const sortedEntries = useMemo(() => {
    return entries.slice().sort((a: TestResult, b: TestResult) => {
      const aLatency = a.latency ?? Number.POSITIVE_INFINITY;
      const bLatency = b.latency ?? Number.POSITIVE_INFINITY;
      if (aLatency === bLatency) {
        return a.url.localeCompare(b.url);
      }
      return aLatency - bLatency;
    });
  }, [entries]);

  const handleAddEndpoint = useCallback(async () => {
    const candidate = customUrl.trim();
    let errorMsg: string | null = null;

    if (!candidate) {
      errorMsg = t("endpointTest.enterValidUrl");
    }

    let parsed: URL | null = null;
    if (!errorMsg) {
      try {
        parsed = new URL(candidate);
      } catch {
        errorMsg = t("endpointTest.invalidUrlFormat");
      }
    }

    // 明确只允许 http: 和 https:
    const allowedProtocols = ["http:", "https:"];
    if (!errorMsg && parsed && !allowedProtocols.includes(parsed.protocol)) {
      errorMsg = t("endpointTest.onlyHttps");
    }

    let sanitized = "";
    if (!errorMsg && parsed) {
      sanitized = normalizeEndpointUrl(parsed.toString());
      // 使用当前 entries 做去重校验
      const isDuplicate = entries.some((entry) => entry.url === sanitized);
      if (isDuplicate) {
        errorMsg = t("endpointTest.urlExists");
      }
    }

    if (errorMsg) {
      setAddError(errorMsg);
      return;
    }

    setAddError(null);
    setLastError(null);

    // 更新本地状态（延迟保存，点击保存按钮时统一处理）
    setEntries((prev) => {
      if (prev.some((e) => e.url === sanitized)) return prev;
      return [
        ...prev,
        {
          id: randomId(),
          url: sanitized,
          isCustom: true,
          latency: null,
          status: undefined,
          error: null,
        },
      ];
    });

    if (!normalizedSelected) {
      onChange(sanitized);
    }

    setCustomUrl("");
  }, [customUrl, entries, normalizedSelected, onChange, t]);

  const handleRemoveEndpoint = useCallback(
    (entry: EndpointEntry) => {
      // 清空之前的错误提示
      setLastError(null);

      // 更新本地状态（延迟保存，点击保存按钮时统一处理）
      setEntries((prev) => {
        const next = prev.filter((item) => item.id !== entry.id);
        if (entry.url === normalizedSelected) {
          const fallback = next[0];
          onChange(fallback ? fallback.url : "");
        }
        return next;
      });
    },
    [normalizedSelected, onChange],
  );

  const runSpeedTest = useCallback(async () => {
    const urls = entries.map((entry) => entry.url);
    if (urls.length === 0) {
      setLastError(t("endpointTest.pleaseAddEndpoint"));
      return;
    }

    setIsTesting(true);
    setLastError(null);

    // 清空所有延迟数据，显示 loading 状态
    setEntries((prev) =>
      prev.map((entry) => ({
        ...entry,
        latency: null,
        status: undefined,
        error: null,
      })),
    );

    try {
      const results = await vscodeApi.testApiEndpoints(urls, {
        timeoutSecs: ENDPOINT_TIMEOUT_SECS[appId],
      });

      const resultMap = new Map(
        results.map((item) => [normalizeEndpointUrl(item.url), item]),
      );

      setEntries((prev) =>
        prev.map((entry) => {
          const match = resultMap.get(entry.url);
          if (!match) {
            return {
              ...entry,
              latency: null,
              status: undefined,
              error: t("endpointTest.noResult"),
            };
          }
          return {
            ...entry,
            latency:
              typeof match.latency === "number"
                ? Math.round(match.latency)
                : null,
            status: match.status,
            error: match.error ?? null,
          };
        }),
      );

      if (autoSelect) {
        const successful = results
          .filter(
            (item) => typeof item.latency === "number" && item.latency !== null,
          )
          .sort((a, b) => (a.latency! || 0) - (b.latency! || 0));
        const best = successful[0];
        if (best && best.url && best.url !== normalizedSelected) {
          onChange(best.url);
        }
      }
    } catch (error) {
      const message =
        error instanceof Error
          ? error.message
          : `${t("endpointTest.testFailed", { error: String(error) })}`;
      setLastError(message);
    } finally {
      setIsTesting(false);
    }
  }, [entries, autoSelect, appId, normalizedSelected, onChange, t]);

  const handleSelect = useCallback(
    (url: string) => {
      if (!url || url === normalizedSelected) return;
      onChange(url);
    },
    [normalizedSelected, onChange],
  );

  // 保存端点变更
  const handleSave = useCallback(async () => {
    // 编辑模式：对比初始端点和当前端点，批量保存变更
    if (isEditMode && providerId) {
      setIsSaving(true);
      setLastError(null);

      try {
        // 获取当前的自定义端点
        const currentCustomUrls = new Set(
          entries
            .filter((e) => e.isCustom)
            .map((e) => normalizeEndpointUrl(e.url)),
        );

        // 找出新增的端点
        const toAdd = Array.from(currentCustomUrls).filter(
          (url) => !initialCustomUrls.has(url),
        );

        // 找出删除的端点
        const toRemove = Array.from(initialCustomUrls).filter(
          (url) => !currentCustomUrls.has(url),
        );

        // 批量添加
        for (const url of toAdd) {
          await vscodeApi.addCustomEndpoint(appId, providerId, url);
        }

        // 批量删除
        for (const url of toRemove) {
          await vscodeApi.removeCustomEndpoint(appId, providerId, url);
        }

        // 更新初始端点列表
        setInitialCustomUrls(currentCustomUrls);
      } catch (error) {
        const message =
          error instanceof Error ? error.message : t("endpointTest.saveFailed");
        setLastError(message);
        setIsSaving(false);
        return;
      } finally {
        setIsSaving(false);
      }
    }

    // 关闭弹窗
    onClose();
  }, [isEditMode, providerId, entries, initialCustomUrls, appId, onClose, t]);

  return (
    <Dialog open={visible} onOpenChange={(open) => !open && onClose()}>
      <DialogContent
        zIndex="nested"
        className="max-w-2xl max-h-[80vh] flex flex-col p-0"
      >
        <DialogHeader className="px-6 pt-6 pb-0">
          <DialogTitle>{t("endpointTest.title")}</DialogTitle>
        </DialogHeader>

        {/* Content */}
        <div className="flex-1 overflow-auto px-6 py-4 space-y-4">
          {/* 测速控制栏 */}
          <div className="flex items-center justify-between">
            <div className="text-sm text-gray-600 dark:text-gray-400">
              {entries.length} {t("endpointTest.endpoints")}
            </div>
            <div className="flex items-center gap-3">
              <label className="flex items-center gap-1.5 text-xs text-gray-600 dark:text-gray-400">
                <input
                  type="checkbox"
                  checked={autoSelect}
                  onChange={(event) => setAutoSelect(event.target.checked)}
                  className="h-3.5 w-3.5 rounded border-border-default "
                />
                {t("endpointTest.autoSelect")}
              </label>
              <Button
                type="button"
                onClick={runSpeedTest}
                disabled={isTesting || !hasEndpoints}
                size="sm"
                className="h-7 w-20 gap-1.5 text-xs"
              >
                {isTesting ? (
                  <>
                    <Loader2 className="h-3.5 w-3.5 animate-spin" />
                    {t("endpointTest.testing")}
                  </>
                ) : (
                  <>
                    <Zap className="h-3.5 w-3.5" />
                    {t("endpointTest.testSpeed")}
                  </>
                )}
              </Button>
            </div>
          </div>

          {/* 添加输入 */}
          <div className="space-y-1.5">
            <div className="flex gap-2">
              <Input
                type="url"
                value={customUrl}
                placeholder={t("endpointTest.addEndpointPlaceholder")}
                onChange={(event) => setCustomUrl(event.target.value)}
                onKeyDown={(event) => {
                  if (event.key === "Enter") {
                    event.preventDefault();
                    handleAddEndpoint();
                  }
                }}
                className="flex-1"
              />
              <Button
                type="button"
                onClick={handleAddEndpoint}
                variant="outline"
                size="icon"
              >
                <Plus className="h-4 w-4" />
              </Button>
            </div>
            {addError && (
              <div className="flex items-center gap-1.5 text-xs text-red-600 dark:text-red-400">
                <AlertCircle className="h-3 w-3" />
                {addError}
              </div>
            )}
          </div>

          {/* 端点列表 */}
          {hasEndpoints ? (
            <div className="space-y-2">
              {sortedEntries.map((entry) => {
                const isSelected = normalizedSelected === entry.url;
                const latency = entry.latency;

                return (
                  <div
                    key={entry.id}
                    onClick={() => handleSelect(entry.url)}
                    className={`group flex cursor-pointer items-center justify-between px-3 py-2.5 rounded-lg border transition ${
                      isSelected
                        ? "border-blue-500 bg-blue-50 dark:border-blue-500 dark:bg-blue-900/20"
                        : "border-border-default bg-white hover:border-border-default hover:bg-gray-50  dark:bg-gray-900 dark:hover:border-gray-600 dark:hover:bg-gray-800"
                    }`}
                  >
                    <div className="flex min-w-0 flex-1 items-center gap-3">
                      {/* 选择指示器 */}
                      <div
                        className={`h-1.5 w-1.5 flex-shrink-0 rounded-full transition ${
                          isSelected
                            ? "bg-blue-500 dark:bg-blue-400"
                            : "bg-gray-300 dark:bg-gray-700"
                        }`}
                      />

                      {/* 内容 */}
                      <div className="min-w-0 flex-1">
                        <div className="truncate text-sm text-gray-900 dark:text-gray-100">
                          {entry.url}
                        </div>
                      </div>
                    </div>

                    {/* 右侧信息 */}
                    <div className="flex items-center gap-2">
                      {latency !== null ? (
                        <div className="text-right">
                          <div
                            className={`font-mono text-sm font-medium ${
                              latency < 300
                                ? "text-green-600 dark:text-green-400"
                                : latency < 500
                                  ? "text-yellow-600 dark:text-yellow-400"
                                  : latency < 800
                                    ? "text-orange-600 dark:text-orange-400"
                                    : "text-red-600 dark:text-red-400"
                            }`}
                          >
                            {latency}ms
                          </div>
                        </div>
                      ) : isTesting ? (
                        <Loader2 className="h-4 w-4 animate-spin text-gray-400" />
                      ) : entry.error ? (
                        <div className="text-xs text-gray-400">
                          {t("endpointTest.failed")}
                        </div>
                      ) : (
                        <div className="text-xs text-gray-400">—</div>
                      )}

                      <button
                        type="button"
                        onClick={(e) => {
                          e.stopPropagation();
                          handleRemoveEndpoint(entry);
                        }}
                        className="opacity-0 transition hover:text-red-600 group-hover:opacity-100 dark:hover:text-red-400"
                      >
                        <X className="h-4 w-4" />
                      </button>
                    </div>
                  </div>
                );
              })}
            </div>
          ) : (
            <div className="rounded-md border border-dashed border-border-default bg-gray-50 py-8 text-center text-xs text-gray-500  dark:bg-gray-900 dark:text-gray-400">
              {t("endpointTest.noEndpoints")}
            </div>
          )}

          {/* 错误提示 */}
          {lastError && (
            <div className="flex items-center gap-1.5 text-xs text-red-600 dark:text-red-400">
              <AlertCircle className="h-3 w-3" />
              {lastError}
            </div>
          )}
        </div>

        <DialogFooter className="gap-2">
          <Button
            type="button"
            variant="outline"
            onClick={onClose}
            disabled={isSaving}
          >
            {t("common.cancel")}
          </Button>
          <Button
            type="button"
            onClick={handleSave}
            disabled={isSaving}
            className="gap-2"
          >
            {isSaving ? (
              <>
                <Loader2 className="w-4 h-4 animate-spin" />
                {t("common.saving")}
              </>
            ) : (
              <>
                <Save className="w-4 h-4" />
                {t("common.save")}
              </>
            )}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
};

export default EndpointSpeedTest;
